﻿WEBVTT

00:00:00.000 --> 00:00:06.000
Translated by visionNoob, KNU
https://github.com/insurgent92/CS231N_17_KOR_SUB

00:00:08.435 --> 00:00:10.602
자 시작합시다.

00:00:13.372 --> 00:00:21.193
이제 5강입니다. 5강에서는 CNN을 배우겠습니다.

00:00:22.493 --> 00:00:25.933
시작하기 전에 몇가지 공지사항이 있습니다.

00:00:25.933 --> 00:00:30.563
첫 번째 과제가 4월 20일 목요일 21:59분에 마감됩니다.

00:00:31.440 --> 00:00:35.607
그리고 그때 두 번째 과제가 나갈 예정입니다.

00:00:38.320 --> 00:00:40.434
우선 지난 강의를 복습해 봅시다.

00:00:40.434 --> 00:00:48.337
지난 몇차례 동안 Neural Networks와 선형 함수들을 살펴보았습니다.

00:00:48.337 --> 00:00:56.969
선형 레이어를 쌓고 그 사이에 비선형 레이어를 추가하여
Neural Network를 만들었습니다.

00:00:56.969 --> 00:01:01.500
또한 NN은  "Mode 문제" 를 해결할 수 있습니다.

00:01:01.500 --> 00:01:06.618
가령 다양한 종류의 자동차를 올바르게 분류하기 위해
"중간 단계의 템플릿"을 학습시키는 것이죠.

00:01:06.618 --> 00:01:09.006
빨간색 차 노란색 차 등을 말이죠.

00:01:09.006 --> 00:01:14.790
그리고 이 템플릿들을 결합해서
최종 클래스 스코어를 계산합니다.

00:01:14.790 --> 00:01:18.438
오늘은 CNN에 대해 말해보고자 합니다.

00:01:18.438 --> 00:01:20.825
기존의 NN과 같은 부류이긴 하지만

00:01:20.825 --> 00:01:23.300
이번에는 Convolutional Layer에 대해 배울 것입니다.

00:01:23.300 --> 00:01:29.217
이 레이어는 기본적으로 "공간적 구조"를 유지합니다.

00:01:31.817 --> 00:01:36.070
우선, Neural Networks에 대해 조금 얘기해 보려 합니다.

00:01:36.070 --> 00:01:39.067
그리고 CNN의 역사도 알아볼 것입니다.

00:01:39.067 --> 00:01:46.308
우선 1957년으로 돌아가보면, Frank Rosenblatt가
 Mark I Perceptron machine 을 개발했습니다.

00:01:46.308 --> 00:01:51.785
이 기계는 "perceptron"을 구현한 최초의 기계입니다.

00:01:51.785 --> 00:01:58.437
"Perceptron"은 우리가 배운 Wx + b 와
유사한 함수를 사용합니다.

00:01:58.437 --> 00:02:02.000
하지만 여기에서는 출력 값이 1 또는 0입니다.

00:02:02.000 --> 00:02:06.551
여기에서도 가중치 W를 Update 하는
Update Rule이 존재합니다.

00:02:06.551 --> 00:02:12.304
이 Update Rule은 Backprop과 유사합니다.

00:02:12.304 --> 00:02:22.349
하지만 당시에는 backprob이라는 개념이 없어서, 단지 W를
이리저리 조절하면서 맞추는 식이었죠

00:02:23.771 --> 00:02:29.673
그리고 1960년에는 Widrow와 Hoff가 \
Adaline and Madaline을 개발했습니다.

00:02:29.673 --> 00:02:37.457
이는 최초의 Multilayer Perceptron Network 이었습니다.

00:02:38.986 --> 00:02:46.658
이 시점에서야 비로소 Neural network와 비슷한
모양을 하기 시작하긴 했지만

00:02:46.658 --> 00:02:50.992
아직 Backprob같은 학습 알고리즘은 없었습니다.

00:02:50.992 --> 00:02:56.015
최초의 Backporp은 1986에 Rumelhart가 제안하였습니다.

00:02:56.015 --> 00:03:03.906
보시다시피 우리에게 익숙한
Chain rule과 Update rule을 볼 수 있습니다.

00:03:03.906 --> 00:03:09.874
이때 최초로 network를 학습시키는 것에 관한
개념이 정립되기 시작했습니다.

00:03:11.623 --> 00:03:18.076
하지만 그 이후로 NN을 더 크게 만들지는 못했습니다.

00:03:18.076 --> 00:03:26.237
그리고 한동안은 새로운 이론이 나오지 못했고
널리 쓰이지도 못 했습니다.

00:03:26.237 --> 00:03:32.790
그래서 2000년대가 되서야 다시 활기를 찾기 시작했습니다.

00:03:33.641 --> 00:03:40.719
Geoff Hinton 과 Ruslan Salakhutdinov의 2006년
논문에서 DNN의 학습가능성을 선보였고

00:03:40.719 --> 00:03:43.212
그것이 실제로 아주 효과적이라는 것을 보여주었습니다.

00:03:43.212 --> 00:03:47.428
하지막 그 때 까지도 아직 모던한 NN는 아니었습니다.

00:03:47.428 --> 00:03:52.439
backprop이 가능하려면 아주 세심하게
초기화를 해야 했습니다.

00:03:52.439 --> 00:03:57.601
그래서 여기에서는 전처리 과정이 필요했고

00:03:57.601 --> 00:04:07.331
초기화를 위해 RBM을 이용해서 각 히든레이어 가중치를
학습시켜야 했습니다.

00:04:07.331 --> 00:04:20.224
이렇게 초기화된 히든 레이어를 이용해서 전체 신경망을
backprop하거나 fine tune하는 것이었습니다.

00:04:23.057 --> 00:04:39.233
실제로 NN의 광풍이 불기 시작한 때는 2012년 이었습니다.

00:04:40.268 --> 00:04:44.980
NN이 음성 인식에서 아주 좋은 성능을 보였습니다.

00:04:44.980 --> 00:04:50.606
이는 Hintin lab에서 나온 것인데 acoustic modeling과
speech recognition에 관한 것이었습니다.

00:04:50.606 --> 00:04:58.604
또한 2012년에는 Hinton lab의 Alex Krizhevsky에서
영상 인식에 관한 landmark paper가 하나 나옵니다.

00:04:59.638 --> 00:05:06.813
이 논문에서는 ImageNet Classification에서 최초로 NN을
사용했고, 결과는 정말 놀라웠습니다.

00:05:06.813 --> 00:05:15.519
AlexNet은 ImageNet benchmark의 Error를
극적으로 감소시켰습니다.

00:05:16.793 --> 00:05:24.236
그 이후로  ConNets은 아주 널리 쓰이고 있습니다.

00:05:24.236 --> 00:05:31.714
다시 돌아가서 구체적으로 "CNN이 어떻게 유명해졌는지"
에 대해 한 번 알아보도록 하겠습니다.

00:05:31.714 --> 00:05:42.538
다시 1950년대로 돌아가보면 Hubel과 Wiesel이 일차시각피질의
뉴런에 관한 연구를 수행했습니다.

00:05:42.538 --> 00:05:45.579
고양이에게 실험을 했습니다.

00:05:45.579 --> 00:05:53.526
첫 수업에서도 이야기하긴 했지만, 고양이의 뇌에 전극을
꽂았습니다.

00:05:53.526 --> 00:05:56.066
그리고 고양이에게 다양한 자극을 주며 실험을 했습니다.

00:05:56.066 --> 00:06:06.937
이 실험에서 뉴런이 oriented edges와 shapes같은 것에
반응한다는 것을 알아냈습니다.

00:06:09.029 --> 00:06:14.993
그리고 이 실험에서 내린 몇 가지 결론은 아주 중요했습니다.

00:06:14.993 --> 00:06:19.534
그중 하나는 바로 피질 내부에
지형적인 매핑(topographical mapping)이 있다는 것입니다.

00:06:19.534 --> 00:06:24.932
피질 내 서로 인접해 있는 세포들은 visual field내에
어떤 지역성을 띄고 있습니다.

00:06:24.932 --> 00:06:34.475
오른쪽 그림은 보면 해당하는 spatial mapping을 볼 수 있습니다.

00:06:34.475 --> 00:06:41.722
그리고 중심에서 더 벗어난 파란색 지역도 볼 수 있습니다.

00:06:41.722 --> 00:06:46.789
또한 이 실험에서 뉴런들이 계층구조를 지닌다는 것도 반견했습니다.

00:06:47.634 --> 00:06:57.837
다양한 종류의 시각자극을 관찰하면서 시각 신호가 가장 먼저
도달하는 곳이 바로 Retinal ganglion 이라는 것을 발견합니다.

00:06:57.837 --> 00:07:01.601
Retinal ganglion cell은 원형으로 생긴 지역입니다.

00:07:01.601 --> 00:07:11.146
가장 상위에는 Simple cells이 있는데, 이 세포들은 다양한
edges의 방향과 빛의 방향에 반응했습니다.

00:07:11.146 --> 00:07:15.448
그리고 더 나아가, 그런 Simple Cells 이
Complex cells과 연결되어 있다는 것을 발견했습니다.

00:07:15.448 --> 00:07:19.923
Complex cells는 빛의 방향 뿐만 아니라 움직임에서 반응했습니다.

00:07:19.923 --> 00:07:28.984
복잡도가 증가함게 따라, 가령  hypercomplex cells은
끝 점(end point) 과 같은것에 반응하게 되는 것입니다.

00:07:28.984 --> 00:07:34.175
이런 결과로부터  "corner" 나 "blob"에 대한
아이디어를 얻기 시작한 것입니다.

00:07:38.143 --> 00:07:52.454
1980의 neocognitron은 Hubel과 Wiesel이 발견한
simple/complex cells의 아이디어를 사용한 최초의 NN입니다.

00:07:52.454 --> 00:07:59.038
Fukishima는 simple/complex cells을 교차시켰습니다.
(SCSCSC..)

00:07:59.038 --> 00:08:03.129
Simple cells은 학습가능한 parameters를 가지고 있고

00:08:03.129 --> 00:08:12.958
Complex cells은 pooling과 같은 것으로 구현했는데
작은 변화에 Simple cells보다 좀 더 강인합니다.

00:08:14.786 --> 00:08:17.159
지금까지는 1980년대 까지의 업적이었습니다.

00:08:17.159 --> 00:08:27.743
1998년 Yann LeCun이 최초로 NN을 학습시키기 위해
Backprob과 gradient-based learning을 적용했고

00:08:27.743 --> 00:08:32.063
실제로 그 방법은 문서인식에 아주 잘 동작했습니다.

00:08:32.063 --> 00:08:37.610
그리고 우편번호의 숫자를 인식하는데도 아주 잘 동작했습니다.

00:08:37.610 --> 00:08:45.082
그리고 실제 우편 서비스에서 우편번호 인식에
널리 쓰였습니다.

00:08:45.082 --> 00:08:56.350
하지만 아직 이 Network를 더 크게만들 수는 없었습니다.
그리고 숫자 라는 데이터는 단순했습니다.

00:08:56.350 --> 00:09:08.900
2012년 Alex Krizhevsky가 CNN의 현대화 바람을 이르켰습니다.
이 Network는 AlexNet이라고도 불립니다.

00:09:08.900 --> 00:09:21.751
Yann LeCun의 CNN과 크게 달라보이진 않습니다.
다만 더 크고 깊어진 것입니다.

00:09:21.751 --> 00:09:37.724
가장 중요한 점은 지금은 ImageNet dataset과 같이 대규모의
데이터를 활용할 수 있다는 것입니다. 또한 GPU의 힘도 있었습니다.

00:09:37.724 --> 00:09:41.033
나중에 더 자세히 다루도록 하죠

00:09:41.033 --> 00:09:45.434
다시 오늘날로 돌아와보면
ConvNets은 모든 곳에 쓰입니다.

00:09:45.434 --> 00:09:55.188
AlexNet의 ImageNet 데이터 분류 결과를 살펴보자면
이미지 검색에 정말 좋은 성능을 보이고 있습니다.

00:09:55.188 --> 00:10:04.134
가령 꽃을 검색하는 것을 보면 학습된 특징이 유사한 것을
매칭시키는데 아주 강력하다는 것을 볼 수 있습니다.

00:10:04.134 --> 00:10:07.049
Detection에서도 ConvNet을 사용합니다.

00:10:07.049 --> 00:10:17.705
영상 내에 객체가 어디에 있는지를 아주 잘 찾아냅니다.
버스나 보트 등을 찾아내고 네모박스를 정확하게 그립니다.

00:10:17.705 --> 00:10:26.112
그리고 그보다 더 어려운 일들도 할 수 있는데 segmentation
은 단지 네모박스만 치는 것이 아니라

00:10:26.112 --> 00:10:32.125
나무나 사람 등을 구별하는데
픽셀 하나 하나에 모두 레이블링하는 것입니다.

00:10:34.126 --> 00:10:38.864
이런 알고리즘은 자율주행 자동차에 사용할 수 있습니다.

00:10:38.864 --> 00:10:48.812
대부분의 작업은 GPU가 수행할 수 있으며, 병렬처리를 통해
ConvNet을 아주 효과적으로 훈련하고 실행시킬 수 있습니다.

00:10:48.812 --> 00:10:59.207
자율 주행에 들어가는 임베디드 시스템에서도 동작할 뿐만 아니라
최신의 GPU에서도 가능합니다.

00:10:59.207 --> 00:11:03.399
이는 모두 Convnet 을 활용할 수 있는 다양한
애플리케이션의 예라고 할 수 있습니다.

00:11:03.399 --> 00:11:10.394
얼굴인식의 예를 보면 얼굴 이미지를 입력으로 받아서
이 사람이 누구인지에 대한 확률을 추정할 수 있습니다.

00:11:12.626 --> 00:11:25.951
ConvNets을 비디오에도 활용할 수 있는데, 단일 이미지의
정보 뿐만 아니라 시간적 정보도 같이 활용하는 방법입니다.

00:11:25.951 --> 00:11:32.770
또한 pose recognition도 가능합니다. 어깨나 팔꿈치와 같은
다양한 관절들을 인식해 낼 수 있습니다.

00:11:32.770 --> 00:11:42.234
여기 우리 조교 Lane의 이미지가 있습니다.
다양하고 비 정형적인 사람의 포즈를 아무 잘 잡아냅니다.

00:11:42.234 --> 00:11:48.465
오늘날 ConvNets을 이용한 pose recognotion은
아주 잘 동작합니다.

00:11:48.465 --> 00:11:51.741
Convnet을 가지고 게임도 할 수 있습니다.

00:11:51.741 --> 00:11:58.595
더 깊은 강화학습을 통해서 Atari 게임을 하거나
바둑을 두는 모습을 보신 적이 있을 것입니다.

00:11:58.595 --> 00:12:02.981
ConvNets은 이 모든 일들에서
아주 중요한 역할을 합니다.

00:12:02.981 --> 00:12:10.150
또다른 예로는 의학 영상을 가지고 해석을 하거나
진단을 하는데도 이용할 수 있습니다.

00:12:10.150 --> 00:12:14.317
또한 은하를 분류하거나 표지판을 인식하는데도 쓰입니다.

00:12:18.059 --> 00:12:22.342
최근의 Kaggle Chanllange에서는
고래를 분류하는 것도 있었습니다.

00:12:22.342 --> 00:12:33.249
또한 항공지도를 가지고 어디가 길이고 어디가 건물인지를
인식하기도 합니다.

00:12:35.089 --> 00:12:41.587
Classification이나 Detection에서 좀 더 나아가는 방법도
있습니다. Image Captioning같은 방법이죠

00:12:41.587 --> 00:12:48.644
이미지가 주어지면 이미지에 대한 설명을
문장으로 만들어 내는 것입니다.

00:12:48.644 --> 00:12:52.819
아마 나중에 배우게 될 것입니다.

00:12:52.819 --> 00:13:01.251
또한 Neural Network를 이용해 간지나는 예술작품도
만들어 낼 수 있습니다.

00:13:01.251 --> 00:13:12.412
왼쪽에 Deep Dream 알고리즘의 결과를 볼 수 있는데
다양한 어떤 객체가 보이고 약빨고 만든듯한 느낌을 줍니다

00:13:12.412 --> 00:13:23.808
또한 Style Transfer라는 방법은 원본 이미지를 가지고
특정 화풍으로 다시 그려주는 알고리즘도 있습니다.

00:13:23.808 --> 00:13:33.370
가령 맨 오른쪽은 반 고흐의 별의 빛나는 밤의 화풍으로 바뀐 것입니다.

00:13:33.370 --> 00:13:38.239
Jstin이 이와 관련된 연구를 많이 합니다.
만약 이에 관심이 있다면

00:13:38.239 --> 00:13:46.244
여기 예제 모두 Justin이 만든 코드이기 때문에
가서 물어보면 될 것입니다.

00:13:46.244 --> 00:13:52.727
지금까지는 오늘날 ConvNets이 어떻게 사용되는지
간략하게 한 번 알아보았습니다.

00:13:52.727 --> 00:13:55.289
물론 이보다 더 많은 일들을 할 수 있을 것입니다.

00:13:55.289 --> 00:14:06.465
때문에 여러분도 무수히 많은 상상을 할 수 있을 것이고
저는 개인적으로 여러분들의 프로젝트가 몹시 기대됩니다.

00:14:06.465 --> 00:14:10.307
오늘은 Convolutional Neural Network가 어떻게
작동하는지를 살펴 볼 것입니다.

00:14:10.307 --> 00:14:22.835
이번에 CNN의 첫 시간이니, CNN이 어떻게 동작하는지에 대해서만 간단하게
이야기해 볼 것입니다.

00:14:25.453 --> 00:14:31.444
지난 강의에서 Fully Connected Layer에 대한
아이디어를 소개해 드렸습니다

00:14:32.878 --> 00:14:36.257
그리고 완전히 연결된 레이어의 경우

00:14:36.257 --> 00:14:48.443
FC Layer에서 하는 일은 어떤 벡터를 가지고 연산을 하는 것이었습니다.
우선 입력으로 32 x 32 x 3 의 이미지가 있었습니다.

00:14:48.443 --> 00:14:56.787
그리고 이 이미지를 길게 펴서
3072차원의 벡터로 만들었습니다.

00:14:56.787 --> 00:15:01.741
그리고 가중치 W가 있어서 벡터와 곱했습니다. (Wx)

00:15:01.741 --> 00:15:05.908
이 예시에서는 W가 10x3072 행렬입니다.

00:15:07.264 --> 00:15:13.943
그리고 activation 을 얻습니다.
이 Layer의 출력입니다.

00:15:13.943 --> 00:15:20.389
10개의 행으로 되어있는데 3072 차원의 입력와
내적을 한 결과라고 할 수 있습니다.

00:15:22.207 --> 00:15:27.892
그러면 어떤 숫자 하나를 얻게 되는데
이는 그 Neuron의 한 값이라고 할 수 있습니다.

00:15:27.892 --> 00:15:32.270
이 예시의 경우 10개의 출력이 있게 됩니다.

00:15:35.417 --> 00:15:44.165
Convolution Layer와 기존의 FC레이어의 주된 차이점이 있다면
Convolution Layer는 기존의 구조를 보존시킨다는 것입니다.

00:15:44.165 --> 00:15:57.750
기존의 FC Layer가 입력 이미지를 길게 쭉 폈다면
이제는 기존의 이미지 구조를 그대로 유지하게 됩니다.

00:15:57.750 --> 00:16:01.910
그리고 이 작은 필터가 우리가 가진 가중치가 되는 것이고

00:16:01.910 --> 00:16:13.153
이 예시에서는 5x5x3 필터가, 이 필터를 가지고 이미지를
슬라이딩하면서 공간적으로 내적을 수행하게 됩니다.

00:16:13.153 --> 00:16:17.320
이제 이것을 어떻게 수행하는지 자세하게 알아보겠습니다.

00:16:18.668 --> 00:16:23.957
우선 필터는 입력의 깊이(Depth)만큼 확장됩니다.

00:16:23.957 --> 00:16:33.425
여기에서 하나의 필터는 아주 작은 부분만 취할 수 있습니다.
전체 32x32 이미지의 5x5 만 취하는 것입니다.

00:16:33.425 --> 00:16:42.499
하지만 깊이를 보면 전체 깊이를 전부 취합니다.
여기에서는 5 x 5 x 3 가 되는 것입니다.

00:16:42.499 --> 00:16:52.901
이제 이 필터를 가지고 전체 이미지에 내적을 시킬 적입니다.

00:16:52.901 --> 00:16:58.636
이 필터를 이미지의 어떤 공간에 겹쳐놓고 내적을 수행합니다.

00:16:58.636 --> 00:17:09.732
그리고 필터의 각 w와, 이에 해당하는 이미지의 픽셀을 곱해줍니다.

00:17:09.733 --> 00:17:18.755
여기에 필터가 5 x 5 x 3 라는건 그만큼 곱셈연산을 한다는 것입니다.
물론 bias term도 하나 들어가겠지만요

00:17:18.755 --> 00:17:26.491
여기에서는 기본적으로 W^tx + b를 수행하는 것입니다.

00:17:27.722 --> 00:17:31.771
이해했나요?
질문있나요

00:17:31.771 --> 00:17:34.521
[학생이 질문]

00:17:35.656 --> 00:17:40.722
그럼 여기에서 내적을 할때는
5x5x3짜리 긴 벡터를 사용하는 것입니까? 입니다.

00:17:40.722 --> 00:17:42.907
맞습니다. 엄밀히 말하면 그렇습니다.

00:17:42.907 --> 00:17:57.891
각 원소끼리 Convolution 을 하는 거나 그것을 쭉 펴서
내적을 하는거나 똑같은 일을 하는 것입니다.

00:17:57.891 --> 00:18:01.111
다른 질문 있으십니까?

00:18:01.111 --> 00:18:03.867
[학생이 질문]

00:18:03.867 --> 00:18:07.997
질문은 바로 왜 W를 Transpose하는지에 대한
직관이 있습니까? 하는 것입니다.

00:18:07.997 --> 00:18:15.978
그런것은 따로 없습니다. 내적을 수학적으로 표현하기 위해서
표현만 그렇게 한 것일 뿐입니다.

00:18:15.978 --> 00:18:29.593
이는 W를 어떻게 표현하느냐의 차이일 뿐입니다.
단지 행벡터를 만들어 주려고 Transpose를 하는 것입니다.

00:18:29.593 --> 00:18:31.989
하지만 여기에 어떤 직관은 없습니다.

00:18:31.989 --> 00:18:42.862
W를 펴서 D차원 벡터로 만들어보면 내적을 하려면
다시 내적을 1 x N 행벡터로 만들어 줘야 겠죠

00:18:42.862 --> 00:18:45.612
[학생이 질문]

00:18:48.263 --> 00:18:49.829
그래, 문제는

00:18:49.829 --> 00:18:53.996
그럼 여기에서 W가 의미하는것은 5x5x3 가 아니라
1 x 75 인 것입니까? 입니다.

00:18:55.180 --> 00:19:02.550
네 맞습니다. Wx에 대해 생각해보면 우선 내적을 수행하기 앞서
W를 길게 펼 것입니다.

00:19:02.550 --> 00:19:09.629
다시말해 5x5x3의 입력값 x더 길게 펴진 벡터의 형태가 되겠죠

00:19:10.913 --> 00:19:16.706
이전 질문과도 유사한데요

00:19:16.706 --> 00:19:27.527
필터를 이미지에 겹쳐놓고 해당하는 값들을 서로 곱합니다
우리가 보기 좋으라고 저렇게 표현을 해 놨지만

00:19:27.527 --> 00:19:35.061
실제로는 모두 펴서 벡터간 내적을 구하는 것입니다.

00:19:35.061 --> 00:19:36.311
질문있나요?

00:19:37.232 --> 00:19:40.740
[학생이 질문]

00:19:40.740 --> 00:19:46.760
질문은 바로 필터를 이미지에 어떻게 슬라이딩 하는지 입니다.
그건 앞으로 배울 내용입니다.

00:19:46.760 --> 00:19:49.510
[학생이 질문]

00:19:52.071 --> 00:20:00.178
질문은 엄밀하게 Convolution을 수행하려면
커널에 180도 회전되어야 하지 않느냐는 것입니다.

00:20:00.178 --> 00:20:09.451
Convolution의 수식을 후에 볼 것이지만 여기에서의 Conv는
좀 더 느슨한 정의라고 할 수 있습니다.

00:20:09.451 --> 00:20:18.738
신호처리 분야에서의 convolution은 실제로
필터를 뒤집은 다음에 연산을 수행합니다.

00:20:18.738 --> 00:20:27.983
하지만 CNN의 Convolution은 의미적인 요소만 가져온
것이기 때문에 걱정하지 않으셔도 됩니다.

00:20:27.983 --> 00:20:37.246
이떤 분이 질문했던, 어떻게 슬라이딩을 하는지에 대해 알아보겠습니다.

00:20:37.246 --> 00:20:49.975
Convolution은 이미지의 좌상단부터 시작하게 됩니다.
그리고 필터의 중앙을 값들을 모으게 됩니다.

00:20:49.975 --> 00:20:57.511
필터의 모든 요소를 가지고 내적을 수행하게 되면
하나의 값을 얻게됩니다.

00:20:57.511 --> 00:21:00.927
그리고 슬라이딩하게 됩니다.

00:21:00.927 --> 00:21:09.442
Conv연산을 수행하는 값들을 다시 Output activation map의
해당하는 위치에 저장하게 됩니다.

00:21:10.352 --> 00:21:15.532
여기 보면 입력 이미지와 출력 activation map의 차원이
다르다는 것을 알 수 있습니다.

00:21:15.532 --> 00:21:20.126
입력은 32 x 32 이고 출력은 28 x  28 이죠

00:21:20.126 --> 00:21:26.364
그래서 우리는 나중에 수학에 대해 설명 할 것입니다. 이 방법이
차원 적으로 어떻게 작동하는지 정확히 알 수 있습니다.

00:21:26.364 --> 00:21:31.393
기본적으로는 어떻게 슬라이딩을 할 것인지를
선택할 수 있습니다.

00:21:31.393 --> 00:21:41.326
슬라이딩여부와 관계없이 입력 값을 두 개씩 뽑아서
연산을 수행할 수도 있을 것입니다.

00:21:41.326 --> 00:21:48.990
출력 행렬의 크기는 슬라이드를 어떻게 하느냐에 따라 다르게됩니다.
하지만 기본적으로는 하나씩 연산을 수행합니다.

00:21:50.180 --> 00:21:58.141
하나의 필터를 가지고 전체 이미지에 Convolution
연산을 수행합니다.

00:21:58.141 --> 00:22:04.731
그러면 activation map이라는 출력값을 얻게 되는 것입니다.

00:22:04.731 --> 00:22:16.250
보통 Convolution Layer에서는 여러개의 필터를 사용합니다.
왜냐하면 필터마다 다른 특징을 추출하고 싶기 때문입니다.

00:22:16.250 --> 00:22:26.359
따라서 우리는 보통 여러개의 필터를 사용합니다. 가령 여기에
두 번째 필터가 있습니다. 초록색의 5 x 5 x 3 필터입니다.

00:22:26.359 --> 00:22:37.425
이 녹색 필터를 연산하고 나면, 앞서 계산했던 activate map과
같은 크기의 새로운 map이 만들어집니다.

00:22:40.081 --> 00:22:43.553
우리는 한 Layer에서 원하는 만큼 여러개의 필터를
사용할 수 있습니다.

00:22:43.553 --> 00:22:51.698
가령 5 x 5 필터가 6개가 있다면
총 6개의 activation map을 얻게 될 것입니다.

00:22:51.698 --> 00:22:58.368
출력 map의 크기는 28 x 28이 되겠죠.

00:23:01.607 --> 00:23:11.152
이 CNN을 어떻게 활용할 지를 조금 말씀드려보면
이런식으로  Cov Layer들의 연속된 형태가 될 것입니다.

00:23:11.152 --> 00:23:16.676
그리고 각각을 쌓아 올리게 되면 보시는 것과 같이
간단한 Linear Layer로 된 Neural Network가 됩니다.

00:23:16.676 --> 00:23:23.057
이제는 그 사이 사이에 activation function을 넣을 것입니다.
가령 ReLU 같은 것들을 사용할 수 있겠죠.

00:23:24.503 --> 00:23:31.257
그렇게 되면 Conv-ReLU 가 반복되겠죠
그리고 가끔은 pooling layer도 들어갑니다.

00:23:31.257 --> 00:23:40.465
그리고 각 Layer의 출력은 다음 Layer의 입력이 됩니다.

00:23:43.638 --> 00:23:52.957
그리고 말씀드렸듯 각 Layer는 여러개의 필터를 가지고 있습니다.
그리고 각 필터마다 각각의 출력 map을 만듭니다.

00:23:52.957 --> 00:24:01.175
그러므로 여러개의 Layer들을 쌓고나서 보면 결국
각 필터들이 계층적으로 학습을 하는것을 보게됩니다.

00:24:01.175 --> 00:24:09.257
앞쪽에 있는 필터들은 low-level feature를 학습하게 됩니다.
Edge와 같은것들이 보입니다.

00:24:09.257 --> 00:24:19.113
Mid-level을 보면 좀더 복잡한 특징을 가지게 됩니다.
코너나 blobs 등과 같이 보입니다.

00:24:19.113 --> 00:24:25.852
그리고 high-level features를 보면 좀 더 객체와 닮은 것들이
출력으로 나오는 것을 볼 수 있습니다.

00:24:25.852 --> 00:24:35.561
나중 수업에서 객 특징을 어떻게 시각화하는지, 그리고 특징들이
어떻게 학습되는지를 살펴보겠습니다.

00:24:35.561 --> 00:24:46.967
여기에서 이해하고 넘어가야 하는 것은 특징이 어떻게 생겼고,
Layer의 계층에 따라 단순/복잡한 특징을이 존재한다는 것을 아는 것입니다.

00:24:48.305 --> 00:24:49.138
[학생이 질문]

00:24:49.138 --> 00:25:03.113
질문은 바로 필터의 Depth를 늘리는데 어떤 직관을 가져야 하는지 입니다.

00:25:03.113 --> 00:25:08.814
이 예시에서 처음에는 3개의 필터가 그 다음에는
6개의 필터가 있었습니다.

00:25:08.814 --> 00:25:17.255
이는 어떻게 모델을 디자인해야 되는지의 문제인데
실제로는 어떤것이 더 좋은지를 찾아내야 합니다.

00:25:17.255 --> 00:25:28.344
나중 수업에서 다양한 CNN 아키텍쳐를 살펴보면서 왜 어떤
모델이 더 좋은지를 살펴볼 것입니다.

00:25:28.344 --> 00:25:33.238
하지만 기본적으로 여러분은 아주 다양하 방법으로
CNN 모델을 디자인할 수 있습니다.

00:25:33.238 --> 00:25:39.611
필터 사이즈라던가 Stride, 그리고 얼마나 많은 필터를
사용할지 등을 말이죠. 다음에 다시 이야기하겠습니다.

00:25:39.611 --> 00:25:41.246
질문있나요?

00:25:41.246 --> 00:25:43.996
[학생이 질문]

00:25:50.300 --> 00:26:00.177
질문은 바로 우리가 전체 이미지를 슬라이딩 하면서 필터링을 하는데
이미지의 가장자리는 필터가 덜 적용되지 않냐는 것입니다.

00:26:00.177 --> 00:26:07.900
아주 좋은 질문 입니다. 그리고 어떻게 그것을 다시 보완해야
하는지가 앞으로 할 내용입니다. (ex zero-padding)

00:26:12.009 --> 00:26:26.228
지금까지는 Conv Layer를 계층적으로 쌓아서 단순한 특징을을 뽑고
그것을 또 조합해서 더 복잡한 특징으로 활용했습니다.

00:26:26.228 --> 00:26:32.549
그리고 이는 Hubel과 Wiesel의 이론과도 잘 맞습니다.

00:26:32.549 --> 00:26:39.532
네트워크에 앞쪽에서는 단순한 것들일 처리하고
뒤로 갈수록 점점 더 복잡해 지는 식이죠

00:26:39.532 --> 00:26:55.041
우리는 그것을 강제로 학습시킨 것이 아니라 계층적 구조를 설계하고
역전파로 학습시킨 것 뿐이지만 필터는 이렇게 학습되는 것입니다.

00:26:55.041 --> 00:26:57.791
[학생의 질문]

00:27:05.555 --> 00:27:10.979
질문은 바로 여기에서 시각화 한 것이
무엇인지 입니다.

00:27:10.979 --> 00:27:20.975
가령 Cov1을 보면 각 그리드의 요소가
하나의 뉴런(필터) 라고 보시면 됩니다.

00:27:20.975 --> 00:27:29.956
그리고 시각화 시킨 이 뉴런의 모습은 바로 이미지가 어떻게 생겨야 해당
뉴런의 활성을 최대화시킬 수 있는지는 나타내는 것입니다.

00:27:29.956 --> 00:27:36.594
이미지가 뉴런과 비슷하게 생겼으면 출력 값을 큰 값을 가지게 됩니다.

00:27:36.594 --> 00:27:56.280
시각화는 Backpopagation을 통해 해볼 수 있는데.
이를 시각화하는 방법은 나중에 더 자세하게 배울 것입니다.

00:27:56.280 --> 00:28:06.775
그러나 기본적으로 여기 그리드의 각 요소는 각 뉴런의 활성을
최대화시키는 입력의 모양을 나타내게 됩니다.

00:28:06.775 --> 00:28:10.608
그런 의미에서 뉴런이 어떻게 생겼는지를 의미합니다.

00:28:13.537 --> 00:28:19.835
Activation map의 예제를 한 번 보겠습니다.
각 필터가 만든 출력값이죠

00:28:19.835 --> 00:28:30.407
위에 5 x 5 필터들을 시각화 한 것을 볼 수 있습니다.
실제 ConvNet을 학습시킨 결과입니다.

00:28:30.407 --> 00:28:38.511
5 x 5 필터가 어떻게 생겼는지를 보여 줍니다. 그리고
이미지와 필터간 Conv의 activation 결과를 볼 수 있습니다.

00:28:38.511 --> 00:28:44.346
이 경우 입력 이미지는 자동차의 한 부분인것 같습니다.

00:28:44.346 --> 00:28:51.330
우선 여기 빨간색 네모박스를 친 필터를 한 번 봅시다.

00:28:51.330 --> 00:28:56.432
이 필터는 edge를 찾고 있는 것입니다.

00:28:56.432 --> 00:29:06.601
그리고 이 필터를 슬라이딩 시키면 이 필터와 비슷한 값들은 값이
더 커지게 됩니다.

00:29:06.601 --> 00:29:12.358
따라서 각 actavation은 이미지가 필터를 통과한
결과가 되며

00:29:12.358 --> 00:29:20.747
이미지 중 어느 위치에서 이 필터가 크게 반응하지는지를
보여줍니다.

00:29:20.747 --> 00:29:29.153
우리가 이걸 Convolution이러고 칭하는 이유는 바로 위에 언급
한 것이 바로 두 신호 사이에 cov를 하는것과 유사하기 때문입니다.

00:29:29.153 --> 00:29:38.927
여기 Conv 식이 있습니다. 예전에 신호처리에서 Conv를 본 적이
있는 학생이라면 이 식이 correlation 같아 보일 것입니다.

00:29:38.927 --> 00:29:50.149
우리는 사실 Conv의 뒤집힌 버전을 쓰고 있는 것입니다.
하지만 이 수업에서는 이를 더 자세히 다루지는 않겠습니다.

00:29:50.149 --> 00:29:58.385
하지만 손으로 직접 계산해보면 conv에 정확한 정의와
크게 다르지 않을 것입니다.

00:29:58.385 --> 00:30:06.432
하지만 기본적으로는 필터를 가지고 이미지에 슬라이딩하면서
모든 위치에서 내적을 수행하게 되는 것입니다.

00:30:09.088 --> 00:30:17.278
이전에도 언급했듯이 CNN이 어떻게 수행되는지를 살펴보면

00:30:17.278 --> 00:30:28.236
입력 이미지는 여러 레이어를 통과하게 됩니다. 가령 첫 번째
Conv Layer 후에는  non-linear layer를 통과합니다.

00:30:28.236 --> 00:30:33.608
나중에 배우겠지만, ReLU를 가장 많이 사용합니다.

00:30:33.608 --> 00:30:41.244
Conv, ReLU, Conv, ReLU를 하고나면 pooling layer를
거치게 됩니다. 다시 배우겠지만-

00:30:41.244 --> 00:30:45.411
pooling 은 activation maps의 사이즈를
줄이는 역할을 합니다.

00:30:47.300 --> 00:30:56.872
그리고 CNN의 끝단에는 FC-Layer가 있습니다.
FC-Layer는 지난시간까지 배운 레이어입니다.

00:30:56.872 --> 00:31:07.178
마지막 Conv 출력 모두와 연결되어 있으며 최종 스코어를 계산하기
위해 사용합니다.

00:31:08.445 --> 00:31:14.181
그럼 이제 "Spatial dimension"에 대해 알아보겠습니다.

00:31:18.363 --> 00:31:28.025
자 여기 32 x 32 x 3 이미지가 있습니다. 그리고 이 이미지를
5 x 5 x 3 필터를 가지고 연산을 수행합니다.

00:31:28.025 --> 00:31:34.337
이제 어떻게 이 둘을 가지고 28 x 28 activation map이
생기는지를 알아보겠습니다.

00:31:34.337 --> 00:31:41.505
간단한 예시로 7 x 7  입력에 3 x 3 필터가 있다고 해봅시다.

00:31:41.505 --> 00:31:47.418
이제 이 필터를 이미지의 왼상당부터 씌웁니다.

00:31:47.418 --> 00:31:53.169
그리고 이제 해당 값들의 내적을 수행할 것입니다.

00:31:53.169 --> 00:31:56.764
이 값들은 activation map의 좌 상단에 위치하게 되겠죠

00:31:56.764 --> 00:32:02.389
그리고 다음 단계로 필터를 오른쪽으로 한칸 움직입니다.

00:32:02.389 --> 00:32:05.535
그러면 값 하나를 또 얻을 수 있을 것입니다.

00:32:05.535 --> 00:32:14.528
이렇게 계속 반복하게 되면  결국 5 x 5의 출력을 얻게 됩니다.

00:32:14.528 --> 00:32:25.381
이 슬라이드 필터는 좌우 방향으로는 5번만 수행가능하고
상하 방향으로도 5번만 수행가능합니다.

00:32:27.834 --> 00:32:31.906
그리고 여기에는 다양한 방법을 이용해 볼 수 있습니다.

00:32:31.906 --> 00:32:40.326
지금까지는 슬라이딩을 한칸씩만 진행했었죠.
이때 움직이는 칸을  바로 "stride" 라고 합니다.

00:32:40.326 --> 00:32:46.700
지금까지는 stide = 1을 사용했습니다.
그럼 stride = 2 일때는 어떨까요?

00:32:46.700 --> 00:32:58.944
다시 왼쪽 위부터 시작해서 움직입니다. 다만 여기에서는
1칸은 건너뛰고 그 다음칸으로 이동해서 계산을 합니다.

00:33:00.773 --> 00:33:11.257
이렇게 tride가 2 이면 3칸이면 못움직이고
결국 출력은 3 x 3 이 됩니다.

00:33:13.035 --> 00:33:18.653
그렇다면 stride = 3 이면 출력의 사이즈는 몇일까요?

00:33:18.653 --> 00:33:27.905
stride가 3인 경우에는 이미지를 슬라이딩해도 필터가
모든 이미지를 커버할 수 없습니다.

00:33:27.905 --> 00:33:32.363
이 예시에서 stride 가 3이면 이미지에 잘 맞아떨어지지 않습니다.

00:33:32.363 --> 00:33:41.903
실제로 이렇게 되면 잘 동작하지 않습니다. 이렇게 하면 안됩니다.
이로 인해 불균형한 결과를 볼 수도 있기 때문입니다.

00:33:46.095 --> 00:33:54.690
그래서 상황에 따라 출력의 사이즈가 어떻게 될 것인지를
계산할 수 있는 아주 유용한 수식이 있습니다.

00:33:54.690 --> 00:34:05.597
입력의 차원이 N이고 필터 사이즈가 F이고
스트라이드가 몇이다 라고 주어지게 되면

00:34:06.992 --> 00:34:12.850
출력의 크기는 (N - F) / stride + 1 이 됩니다.

00:34:12.850 --> 00:34:18.619
이를 이용해서 어떤 필터 크기를 사용해야 하는지를 알 수 있습니다.

00:34:18.620 --> 00:34:27.326
그리고 어떤 stride를 사용했을때 이미지에 꼭 맞는지,
그리고 몇 개의 출력값을 낼 수 있는지도 알 수 있습니다.

00:34:29.257 --> 00:34:32.546
지금까지 유용한 수식을 한 번 알아봤습니다.

00:34:32.547 --> 00:34:38.637
앞서 보신바와 같이 N = 7 이고 F = 3 일때,
그리고 stride가 1이면

00:34:38.637 --> 00:34:43.498
이걸 그대로 수식에 적용해보면 5 x 5 출력이
나올 것이라는 것을 알 수 있습니다.

00:34:43.498 --> 00:34:47.665
stride가 3인 경우를 보면, 잘 동작하지 않겠죠. (2.33)

00:34:50.288 --> 00:34:59.552
그리고 가장 흔히 쓰는 기법은 zero-pad 입니다.
출력의 사이즈 의도대로 만들어 주기 위해서죠

00:34:59.552 --> 00:35:04.140
이는 이전 질문이었던 "코너는 어떻게 처리하나요"
와도 연결되는 문제입니다.

00:35:04.140 --> 00:35:09.222
이를 위해 할 일은, 이미지의 가장자리에 0을 채워 넣는 것입니다.

00:35:09.222 --> 00:35:19.134
이렇게 되면 좌 상단의 자리에서도 필터 연산을
수행할 수 있게 됩니다.

00:35:19.134 --> 00:35:33.654
자 이제 다시 질문입니다. 7 x 7 입력에 3 x 3 필터 연산을 수행할 때
zero-padding을 하면 출력이 어떻게 될까요?

00:35:33.654 --> 00:35:36.285
[학생들이 대답]

00:35:36.285 --> 00:35:44.847
몇 명이 6이라고 하는 것 같은데요
저 수식을 한 번 잘 생각해 보세요

00:35:44.847 --> 00:35:52.594
N에 7을, F에 3을 대입하고 stride를 1으로 하면

00:35:52.594 --> 00:35:57.264
그래서 우리가 실제로 얻는 것, 실제로
이것은 우리에게주는 것입니다.

00:35:57.264 --> 00:36:06.707
(7 - 3) /1 + 1 = 5 입니다. 이건 zero-padding이 없고
우리는 이 수식을 살짝 고쳐야합니다.

00:36:06.707 --> 00:36:12.161
이 수식은 zero-padding을 하지 않은 수식이죠

00:36:12.161 --> 00:36:24.173
하지만 zero-padding을 하면 출력이 7이 됩니다.
그래서 결국 7 x 7 출력을 얻게 되는 것입니다.

00:36:24.173 --> 00:36:30.178
원래 공식으로 돌아가보자면 N은 7이 아니라 9가 되겠죠

00:36:30.178 --> 00:36:42.253
N = 9 가 되고 필터 사이즈인 3을 빼면 6이 됩니다. 이를 stride
1나누면 다시 6이고 여기에 1을 더하면 7이 됩니다.

00:36:42.253 --> 00:36:47.974
padding을 하려면 수식을 이런식으로 적용하면 되겠습니다.

00:36:49.739 --> 00:36:51.646
질문 있나요?

00:36:51.646 --> 00:36:54.396
[학생이 질문]

00:37:00.717 --> 00:37:08.962
질문은 "실제 출력 값의 사이즈는 몇입니까?
7 x 7 입니까 7 x 7 x 3 입니까?" 입니다.

00:37:08.962 --> 00:37:14.495
출력은 7 x 7 x "필터의 갯수" 가 됩니다.

00:37:14.495 --> 00:37:21.320
명심해야할 점은 각 필터가 입력의 모든 depth에
내적을 수행한다는 것입니다.

00:37:21.320 --> 00:37:23.801
하나의 값만 나오겠죠

00:37:23.801 --> 00:37:37.124
다시 이전 슬라이드로 돌아가보겠습니다. 이전의 예제에서는
각 필터는 7 x 7 x 1이 되겠죠

00:37:37.124 --> 00:37:40.493
activation map의 depth는 우리가 가진 필터의 갯수입니다.

00:37:40.493 --> 00:37:43.243
[학생이 질문]

00:37:50.161 --> 00:37:57.350
잘 못들었습니다?

00:37:57.350 --> 00:38:00.267
[다시 질문]

00:38:12.936 --> 00:38:19.735
질문은 바로, 이전 예제에서는 32 x 32 x 3 의 입력이었는데,
방금 설명한 것을 어떻게 적용할 수 있는지 입니다.

00:38:19.735 --> 00:38:24.721
이전 예제에서는 depth가 있었는데
지금 예제에서는 depth가 없었죠

00:38:24.721 --> 00:38:27.226
여기에서는 단순하게 예제를 만들었지만

00:38:27.226 --> 00:38:34.188
실제로는 이전에 했던것 처럼 depth만큼 곱해주면 됩니다.

00:38:34.188 --> 00:38:39.850
그러니 이 예제에서 3 x 3 x "depth" 가 되겠습니다.

00:38:39.850 --> 00:38:46.854
그러니 이전 예제의 경우 3 x 3 x 3 이 되겠고
다른 것을 다 똑같습니다.

00:38:46.854 --> 00:38:48.390
질문 있나요?

00:38:48.390 --> 00:38:51.307
[학생이 질문]

00:38:53.529 --> 00:38:58.664
질문은 바로 0 을 padding 하게되면 모서리에
필요없는 특징을 추가하게 되는게 아닌지 입니다.

00:38:58.664 --> 00:39:06.289
우리가 지금 하고싶은 일은 영상 내에 어떤 모서리 부분에서
값을 얻고싶은 것이고

00:39:06.289 --> 00:39:10.343
zero-padding은 이를 할 수 있는 하나의 방법일 뿐입니다.

00:39:10.343 --> 00:39:16.097
우리는 지금  필터가 닿지 않는 모서리 부분에서도 값을
뽑을 수 있게 됩니다.

00:39:16.097 --> 00:39:18.323
물론 zero-padding 말고 다른 방법을 사용할 수도 있습니다.

00:39:18.323 --> 00:39:23.615
zero가 아닌 mirror나 extend하는 방법도 있습니다.
꼭 zero-padding을 써야 하는 것은 아닙니다.

00:39:23.615 --> 00:39:26.530
하지만 zero-padding도 제법 잘 동작하는 방법 중 하나입니다.

00:39:26.530 --> 00:39:36.486
물론 모서리 부분에 약간의 artifact이 생긴 순 있습니다. 당연히
고려해야 하 부분이죠. 하지만 대부분의 경우 제법 잘 동작합니다.

00:39:36.486 --> 00:39:41.283
다른 질문도 있었던 것 같은데요

00:39:41.283 --> 00:39:44.033
[학생이 질문]

00:39:48.015 --> 00:39:54.330
이미지가 정사각 행렬이 아니라면 수평, 수직방향의
stride를 다르게 적용해야 하는지 입니다.

00:39:54.330 --> 00:40:02.841
물론 당연히 가능합니다. 하지만 보통은 정사각 행렬을
사용하고 같은 stride를 적용합니다.

00:40:02.841 --> 00:40:08.238
보통은 모든 영역에 같은 Stride를 적용합니다.

00:40:08.238 --> 00:40:10.218
어떤 의미에서 그것은 조금 비슷합니다.

00:40:10.218 --> 00:40:20.693
이는 이미지 해상도 문제와도 관련이 있습니다. 아마 여러분은
입력 이미지의 종횡비를 유지하고 싶을 것이지만

00:40:20.693 --> 00:40:28.373
대부분의 사람들은 정사각으로 사용합니다.
(잘 대답한건지 모르겠음)

00:40:28.373 --> 00:40:31.453
[학생이 질문]

00:40:31.453 --> 00:40:33.710
질문을 바로 왜 zero-padding을 하냐는 것입니다.

00:40:33.710 --> 00:40:39.376
 zero-padding을 하는 이유는 레이어를 거치면서도
입력의 사이즈를 유지하기 위해서입니다.

00:40:39.376 --> 00:40:49.019
가령 7 x 7 필터를 연산한다고 하면 출력의 사이즈는
입력보다 작아집니다.

00:40:49.019 --> 00:40:53.186
하지만 우리는 지금 그 사이즈를 유지하고 싶은 것입니다.

00:40:56.276 --> 00:41:10.753
지금까지 Padding을 하게되면 출력 사이즈를 유지시켜주고 필터의
중앙이 닿지 않는 곳도 연산할 수 있다는 것을 배웠습니다.

00:41:10.753 --> 00:41:18.998
어떤 stride와 filter를 쓸건지를 일반적으로 정하는 방법이 있습니다.

00:41:18.998 --> 00:41:25.427
보통 filter는 3x3, 5x5, 7x7 을 씁니다.

00:41:25.427 --> 00:41:33.567
보통 3x3 filter에는 stride를 1로 줍니다.

00:41:33.567 --> 00:41:39.422
그리고 5x5 filter에는 보통 stride를 2로 주죠

00:41:39.422 --> 00:41:43.505
7x7 일때는 3을 줍니다.

00:41:44.722 --> 00:41:52.184
다시 한 번 말하지만 zero-padding을 하는 목적은
입력 사이즈와 출력 사이즈를 같도록 하기 위해서 입니다.

00:41:52.184 --> 00:42:10.566
이전에 말했듯이 레이어가 여러겹 쌓인다고 생각해 보면
그리고 그때 zero-padding을 하지 않는다면

00:42:10.566 --> 00:42:16.616
출력 사이즈는 아주 빠르게 줄어들게됩니다.
우리가 원하는 결과는 아니죠

00:42:16.616 --> 00:42:25.907
만일 엄청 깊은 네트워크가 있다고 생각해보면
Activation Map은 점점 줄어들어 엄청 작아지게 될 것입니다.

00:42:25.907 --> 00:42:36.578
그렇게 되면 일부 정보를 잃게 되는 것이고
원본 이미지를 표현하기에 너무 작은 값을 사용하게 될 것입니다.

00:42:36.578 --> 00:42:53.590
그리고 그렇게 줄어드는 이유는 매번 각 코너에 있는 값들을
계산하지 못하기 때문입니다.

00:42:55.203 --> 00:43:00.060
자 그럼 몇가지 예를 더 살펴보겠습니다.

00:43:00.991 --> 00:43:09.244
여기에 입력 이미지 32 x 32 x 3 이 있습니다.
그리고 10개의 5 x 5 필터도 있습니다.

00:43:09.244 --> 00:43:16.717
여기 stride를 1로하고 padding을 2로 했을때
 출력사이즈는 몇이 될까요?

00:43:18.188 --> 00:43:21.728
이전 공식을 한 번 생각해 보세요.

00:43:21.728 --> 00:43:23.263
[학생이 대답]

00:43:23.263 --> 00:43:26.180
32 x 32 x 10 네 맞습니다.

00:43:27.572 --> 00:43:33.707
입력 사이즈 F는 32이죠

00:43:33.707 --> 00:43:41.209
padding으로 이 값을 2씩 증가시킵니다.
각 차원에 값을 2 증가시킵니다.

00:43:41.209 --> 00:43:47.181
그렇게 각 양쪽에 2씩 추가시키면
32 + 4 가 되겠죠

00:43:47.181 --> 00:43:49.992
그리고 필터사이즈 5를 뺴줍니다.

00:43:49.992 --> 00:43:51.716
그리고 다시 1을 더하면 32를 얻게 됩니다.

00:43:51.716 --> 00:43:55.883
그러면 각 필터는 32 x 32가 됩니다.

00:43:57.213 --> 00:44:02.193
전체 필터의 갯수는 10개이니
10개의 activation map이 나오겠죠

00:44:02.193 --> 00:44:06.360
그럼 전체 출력의 크기는
32 x 32 x 10 이 됩니다.

00:44:08.244 --> 00:44:14.478
자 그럼 다음 질문입니다.
이 레이어의 파라미터는 총 몇개일까요?

00:44:14.478 --> 00:44:18.145
우리에게 10개의 5 x 5 필터가 있다는 것이 힌트입니다.

00:44:19.769 --> 00:44:22.698
[학생이 질문]

00:44:22.698 --> 00:44:36.226
잘 못들었습니다?
250이라고 답했습니다.

00:44:37.829 --> 00:44:42.149
명심해야 할 점은 필터가 입력의 Depth만큼도 통과한다는 것입니다.

00:44:42.149 --> 00:44:50.300
이 슬라이드에는 그 내용이 명확히 쓰여있지는 않습니다.
하지만 묵시적으로 여기에 Depth도 존재합니다.

00:44:50.300 --> 00:44:55.876
필터가 입력의 전체 depth를 통과하게 되겠죠.
750이라는 정답을 들은것 같습니다.

00:44:55.876 --> 00:45:03.374
거의 다 근접했습니다. 우리는 여기 bias term도 있다는
것을 명심해야 합니다.

00:45:03.374 --> 00:45:08.084
이 각각의 5 x 5 x 3 가중치에는
하나의 bias term이 들어있습니다.

00:45:08.084 --> 00:45:15.609
그러니 필터당 76개의 파라미터가 있는 것이고 이런 필터가
총 10개 있으니 전체 760개의 파라미터가 있는 것입니다.

00:45:18.412 --> 00:45:25.890
자 여기에 Conv layer를 한 번 요약정리해 보았습니다.
나중에 주의깊게 읽어보시기 바랍니다.

00:45:25.890 --> 00:45:31.137
어떤 n차원의 입력이 있습니다.
그리고 어떤 필터를 쓸지 선택해야 합니다.

00:45:31.137 --> 00:45:38.682
몇개의 필터를 쓸건지, 필터 크기는 몇인지, stride는 몇으로 할지
zero-padding은 몇 으로 할지를 다 정해줘야합니다.

00:45:38.682 --> 00:45:43.866
그리고 앞서 말한 수식을 이용해서 출력의 사이즈가 어떻게
될 것인지를 계산해 봅니다.

00:45:43.866 --> 00:45:48.033
그리고 전체 파라미터가 몇개가 될 것인지도
확인해 봐야 합니다.

00:45:49.282 --> 00:45:58.555
여기에는 일반적으로 사용하는 값들이 있습니다.
필터 사이즈는 3x3, 5x5 를 씁니다.

00:45:58.555 --> 00:46:01.739
Stride는 보통 1이나 2가 가장 흔합니다.

00:46:01.739 --> 00:46:10.401
그리고 padding은 그 설정에 따라 조금씩 다르겠죠

00:46:10.401 --> 00:46:19.009
그리고 보통 필터의 갯수는 2의 제곱수로 합니다.
32, 64, 128, 512 와 같이 말이죠

00:46:19.903 --> 00:46:24.505
위의 숫자들은 아주 자주 보게될 것입니다.

00:46:24.505 --> 00:46:29.488
우선 다음으로 넘어가서,
1 x 1 Convolution에 대해 말해봅시다.

00:46:29.488 --> 00:46:35.852
1 x 1 Convolution도 의미가 있습니다. 똑같이 슬라이딩 하면서
값을 구하게 되겠죠

00:46:35.852 --> 00:46:46.680
하지만 여기에서는 5x5 처럼 공간적인 정보를 이용하지 않습니다.
하지만 이 필터는 여전히 Depth만큼 연산을 수행합니다.

00:46:46.680 --> 00:46:52.053
그러니 1 x 1 Conv는 입력의 전체 Depth에 대한
내적을 수행하는 것과 같습니다.

00:46:52.053 --> 00:47:07.062
입력은 56x56x64 입니다. 그리고 여기에 32개의 1x1
Conv 수행하면 56x56x32의 출력값이 나오게 됩니다.

00:47:10.076 --> 00:47:16.210
자 여기 TORCH로 구현된 Conv Layer 예제가 있습니다.

00:47:16.210 --> 00:47:25.017
지난 시간에 Torch에 대해 알아봤었는데요
Torch에서는 다양한 레이어가 정의되어 있습니다.

00:47:25.017 --> 00:47:28.667
그리고 그 레이어의 forward/backward pass가
구현되어 있습니다.

00:47:28.667 --> 00:47:35.360
여기 spatial convolution이 바로 그 중 하나입니다.

00:47:35.360 --> 00:47:42.781
여기에 arguments를 가지고 여러 디자인을 선택할 수 있습니다.
입/출력 사이즈를 정할수도 있고

00:47:42.781 --> 00:47:50.161
커널 사이즈, Padding 와 같은 것들을 전부 정해줄 수 있습니다.

00:47:50.161 --> 00:47:54.737
또한 다른 프레임워크인 Caffe를 살펴봅시다.
뭐 다들 비슷비슷 합니다.

00:47:54.737 --> 00:48:07.160
여기 보면 네트워크가 정의되어있는데 Caffe에서는 proto
text라는 파일을 이용합니다. 여기에 디자인을 명시합니다.

00:48:07.160 --> 00:48:18.244
여기 conv layer의 예시가 있는데 출력의 사이즈나 필터의 갯수,
커널 사이즈 stride 등등을 여기에 명시하는 것입니다.

00:48:21.144 --> 00:48:29.512
진행하기에 앞서, 혹시 Conv 연산에 대한 질문이 있습니까?

00:48:30.868 --> 00:48:32.161
네 질문해주세요

00:48:32.161 --> 00:48:34.911
[학생이 질문]

00:48:51.604 --> 00:48:55.902
질문은 바로 stride를 선택하는데 있어 가질 수 있는
직관은 무엇인지 입니다.

00:48:55.902 --> 00:49:09.258
우선 한가지는 stride를 크게 가져갈수록 출력은 점점 작아집니다.

00:49:09.258 --> 00:49:23.025
이미지를 다운샘플링하는 것은 Pooling을 하는것과 비슷합니다. 하지만
그 둘은 확실이 다르고, pooling보다 더 좋은 성능을 보이기도 합니다.

00:49:23.025 --> 00:49:27.192
Pooling 처럼 다운 샘플링하는 동일한 효과를 얻으면서도
더 좋은 성능을 낼 수도 있습니다.

00:49:28.183 --> 00:49:40.825
그리고 activation map의 사이즈를 줄이는 것은 추후
모델의 전체 파라미터의 갯수에도 영향을 미칩니다.

00:49:40.825 --> 00:49:48.611
가령 Conv Layer의 마지막에는 FC Layer가 있을 수 있겠죠.

00:49:48.611 --> 00:49:56.099
FC Layer는 Conv의 출력 모두와 연결되어 있습니다.

00:49:56.099 --> 00:50:02.596
Conv Layer의 출력이 작을수록
FC Layer에서 필요한 파라미터의 수가 더 작겠죠

00:50:02.596 --> 00:50:10.076
파라미터의 수, 모델의 사이즈 그리고 Overfitting 과 같은 것들에는
다양한 trade-off 가 있습니다.

00:50:10.076 --> 00:50:15.538
이 trade-off는 stride를 몇 으로 할지를
결정할때 고려해야 하는 문제입니다.

00:50:18.496 --> 00:50:25.356
자 그럼 Conv Layer을 Brain Neuron의 관점에서 살펴보겠습니다.

00:50:25.356 --> 00:50:31.599
뉴런에 대해서는 지난 시간에 조금 배웠었죠

00:50:31.599 --> 00:50:39.216
Conv Layer를 보면, 전체 이미지의 특정 위치에 필터를 가지고
내적을 수행했습니다.

00:50:39.216 --> 00:50:42.077
그러면 하나의 값을 얻게 됩니다.

00:50:42.077 --> 00:50:46.042
이는 여기 오른쪽 그림의 내적과 같은 아이디어입니다.

00:50:46.042 --> 00:50:55.227
입력이 들어오면 Ws와 곱하고, Ws는 필터 값이죠
그리고 하나의 값을 출려합니다.

00:50:55.227 --> 00:50:59.517
하지만 가장 큰 차이점은 우리의 뉴런은
Local connectivity 를 가지고 있다는 것입니다.

00:50:59.517 --> 00:51:06.536
Conv Layer처럼 슬라이딩을 하는게 아니라
특정 부분에만 연결되어 있습니다.

00:51:06.536 --> 00:51:17.500
하나의 뉴런은 한 부분만 처리하고, 그런 뉴런들이
모여서 전체 이미지를 처리하는 것입니다.

00:51:17.500 --> 00:51:26.652
이런 식으로 spatial structure를 유지한 채로
Layer의 출력인 activation map을 만드는 것입니다.

00:51:30.048 --> 00:51:36.931
중요한 용어들을 한 번 정리해 보겠습니다.
가령 5 x 5 필터가 있다고 해봅시다.

00:51:36.931 --> 00:51:41.726
한 뉴런의  "Receptive field" 가 5 x 5 다
라고 할 수 있습니다.

00:51:41.726 --> 00:51:48.518
"Receptive field" 란 한 뉴런이 한 번에 수용할 수 있는
영역을 의미합니다.

00:51:48.518 --> 00:51:53.315
자주 등장하는 용어이니 익숙해 지시기 바랍니다.

00:51:53.315 --> 00:51:55.743
그런 다음 5 개의 필터로 5 개를 다시 기억하십시오.

00:51:55.743 --> 00:52:03.089
그 필터가 슬라이딩하면서 계산을 하는데 중요한 것은
필터 값이 항상 같다는 것입니다.

00:52:05.440 --> 00:52:11.200
그럼 이제 출력 값에 대해 알아보면 출력 값은
여기 보이는 파란색 Volume 처럼 생길 것입니다.

00:52:11.200 --> 00:52:16.373
크기는 28 x 28 x (필터의 갯수) 가 될텐데요.

00:52:16.373 --> 00:52:23.381
필터가 총 5종류가 있는 경우라면
출력은 28 x 28 x 5 인 3D Grid가 됩니다.

00:52:23.381 --> 00:52:36.003
그러면 이제 어떤 한 점을 찍어서 depth방향으로 바라보면
(파란색 Map 안에 5개 점)

00:52:36.003 --> 00:52:40.590
이 5개의 점은 정확하게 같은 지역에서 추출된
서로다른 특징이라고 할 수 있습니다.

00:52:40.590 --> 00:52:42.344
하지만 각 필터는 서로 다른 특징을 추출합니다.

00:52:42.344 --> 00:52:48.120
그러므로 각 필터는 이미지에서 같은 지역을 돌더라도
서로 다른 특징을 뽑아낸다고 볼 수 있습니다.

00:52:49.152 --> 00:52:55.443
복습겸 다시 FC Layer를 한 번 살펴보겠습니다.

00:52:55.443 --> 00:53:06.637
FC-Layer 의 경우면 32 x 32 x 3 을 다 편 다음에
전체를 연결하여 계산할 것입니다.

00:53:06.637 --> 00:53:12.805
Conv Layer가 전체가 아직 지역정보만 이용하다는 점과
비교해 보시면 될 것 같습니다.

00:53:12.805 --> 00:53:14.255
질문 있나요?

00:53:14.255 --> 00:53:17.088
[학생이 질문]

00:53:22.648 --> 00:53:28.137
Layer 내에서 filter가 하는 일이  Symmetric하냐는 것입니다.

00:53:30.158 --> 00:53:34.325
어떤 점에서 Symmetric하다는 것을 질문하는것인가요?

00:53:42.200 --> 00:53:50.556
필터들이 같은 차원을 가지고 같은 계산을 한다는 것을
의미하는 것  같은데요.

00:53:52.784 --> 00:53:59.624
필터 연산을 할때 다른 특수한 경우가 있냐는 질문입니다.
답은 없습니다.

00:53:59.624 --> 00:54:04.973
가령 우리가 5 x 5 필터가 있다면

00:54:04.973 --> 00:54:11.502
슬라이딩 할때마다 같은 연산을 수행하고,
그렇게 나온 값이 activation map입니다.

00:54:14.596 --> 00:54:20.592
좋습니다 지금까지 Conv Layer 꽤 심도깊게 살펴보았습니다.

00:54:20.592 --> 00:54:28.802
지금부터는 CNN에 들어가는 다른 Layer를 살펴보겠습니다.

00:54:28.802 --> 00:54:36.653
CNN에는 Conv Layer와 Pooling Layer가 있었죠.
그리고 다른 비선형 연산들도 있습니다.

00:54:36.653 --> 00:54:42.716
Pooling Layer는 Representation들을
더 작고 관리하게 쉽게 해줍니다.

00:54:42.716 --> 00:54:51.562
누가 이전에 왜 Representation을 작게 만드냐고 했엇죠

00:54:51.562 --> 00:54:58.343
다시 한 번 말하지만, 작아지면 파라미터의 수가 줄게 됩니다.

00:54:58.343 --> 00:55:04.425
그리고 일종의 공간적인 불변성(invaiance)
을 얻을 수도 있습니다.

00:55:04.425 --> 00:55:09.460
Pooling Layer가 하는 일은 아주 간단합니다.
Downsample 하는 거죠

00:55:09.460 --> 00:55:20.861
가령 224 x 224 x 64 인 입력이 있다면, 이를
112 x 112 x 64 로 "공간적"으로 줄여줍니다.

00:55:20.861 --> 00:55:26.588
중요한 점은 "Depth"에는 아무 짓도 하지 않는다는 것입니다.

00:55:26.588 --> 00:55:36.948
따라서 Depth에는 영향을 주지 않습니다.
그리고 Max Pooling이 일반적으로 쓰입니다.

00:55:36.948 --> 00:55:46.825
Pooling에도 필터 크기를 정할 수 있습니다.
얼마만큼의 영역을 한 번에 묶을지를 정하는 것입니다.

00:55:46.825 --> 00:55:53.572
여기 2 x 2 필터가 있습니다.
그리고 여기에서 Stride는 2 입니다.

00:55:53.572 --> 00:56:01.672
그리고  Conv Layer가 했던 것 처럼 슬라이딩하면서
연산을 수행합니다.

00:56:01.672 --> 00:56:08.338
대신 내적을 하는 것이 아니라, 필터 안에 가장
큰 값 중에 하나를 고르는 것입니다.

00:56:08.338 --> 00:56:15.655
여기 빨간색 영역을 보면 6이 제일 큽니다.
녹색을 보면 8이 제일 크죠

00:56:15.655 --> 00:56:18.655
나머지도 마찬가지로 3과 4의 값이 되겠습니다.

00:56:23.433 --> 00:56:24.931
질문있나요?

00:56:24.931 --> 00:56:27.848
[학생이 질문]

00:56:29.010 --> 00:56:34.406
네 질문은 Pooling 할 때 겹치지 않는 것이 일반적입니까?
입니다

00:56:34.406 --> 00:56:41.256
네 맞습니다. 보통은 겹치지 않는 것이 일반적입니다.

00:56:41.256 --> 00:56:50.560
기본적으로 Downsample을 하고싶은 것이기 때문에

00:56:50.560 --> 00:56:55.874
한 지역을 선택하고 값 하나 뽑고, 또 다른 지역 선택하고
값 하나 뽑고 이런식으로 진행합니다.

00:56:55.874 --> 00:56:57.379
질문있나요?

00:56:57.379 --> 00:57:00.129
[학생이 질문]

00:57:02.415 --> 00:57:07.636
Max pooling이 average pooling보다 더 좋은 이유는
무엇인지? 입니다.

00:57:07.636 --> 00:57:12.017
좋은 질문입니다. Average Pooling도
물론 사용할 수 있습니다.

00:57:12.017 --> 00:57:17.979
왜 max pooling을 주로 사용하지는지에
대한 직관을 설명드리자면

00:57:17.979 --> 00:57:26.972
우리가 다루는 값들은, 얼마나 이 뉴런이
활성되었는 지를 나타내는 값 들입니다.

00:57:26.972 --> 00:57:29.253
즉, 이 필터가 각 위치에서 얼마나 활성되었는지 입니다.

00:57:29.253 --> 00:57:39.133
Max pooling은 그 지역이 어디든,  어떤 신호에 대해 "얼마나"
그 필터가 활성화 되었는지를 알려준다고 알 수 있습니다.

00:57:39.133 --> 00:57:46.535
우리가 "인식" 에 대해 생각해보면
어느정도의 직관을 얻을 수 있는데,

00:57:46.535 --> 00:57:57.073
그 값이 어디에 있었다는 것 보다는
그 값이 얼마나 큰지가 중요한 것입니다.

00:57:57.940 --> 00:57:59.129
질문 있나요?

00:57:59.129 --> 00:58:02.046
[학생이 질문]

00:58:06.200 --> 00:58:14.223
질문은 바로 "Pooling" 이나 Conv Layer의 "Stride"나
매한가지 아니냐는 것입니다.

00:58:14.223 --> 00:58:27.704
네 맞습니다. 요즘들어 사람들이 Downsample할때 pooling을
하기보단 stride를 많이 사용하고 있는 추세입니다.

00:58:27.704 --> 00:58:32.801
제 생각에는 Pooling 도 일종의
Stride 기법이라고 볼 수 있다고 봅니다.

00:58:32.801 --> 00:58:41.892
실제로 요즘은 stride가 더 좋은 성능을 보이는 것 같습니다.

00:58:41.892 --> 00:58:47.292
그러니 당연히 Conv Layer의 stride를 사용해도 무방합니다.
그리고 사람들도 그렇게 하고 있습니다.

00:58:49.672 --> 00:59:00.358
다시 Pooling Layer로 돌아가 봅시다.
Pooling Layer에는 몇가지 Design Choice가 있습니다.

00:59:00.358 --> 00:59:10.107
입력이 W(width), H(Height), D(Depth) 면
이를 통해 Filter Size를 정해줄 수 있습니다.

00:59:10.107 --> 00:59:21.325
여기에 Stride까지 정해주면, 앞서 Conv Layer에서 사용했던
수식을 그대로 이용해서 Design Choice를 할 수 있습니다.

00:59:21.325 --> 00:59:27.780
이렇게 (W - Filter Size) / Stride + 1
로 구하면 됩니다.

00:59:30.880 --> 00:59:41.262
한가지 특징이 있다면 pooling layer에서는 보통 padding을
하지 않습니다. 왜냐면 우리는  downsampling하고 싶고,

00:59:41.262 --> 00:59:47.045
또한 Conv 때처럼 코너의 값을 계산하지 못하는 경우도
없기 때문입니다.

00:59:47.045 --> 00:59:52.939
그러므로 Pooling 할때는 padding을 고려하지 않아도 되고
그냥 downsample만 하면 됩니다.

00:59:52.939 --> 01:00:06.269
가장 널리 쓰이는 필터사이즈는 2 x 2, 3 x 3 이고
보통 stride는 2로 합니다.

01:00:06.269 --> 01:00:14.956
필터가 3 x 3 일때도 보통 stride는 2 x 2 로 합니다.
앞서 언급했듯, 2 x 2 가 좀더 자주 쓰입니다.

01:00:17.958 --> 01:00:21.527
우리는 지금 Conv Layer를 배우고 있습니다.

01:00:21.527 --> 01:00:31.492
ReLU Layer는 지난 강의에 했던것과 같습니다.

01:00:31.492 --> 01:00:37.865
그리고 downsampling을 하고싶을때는 Pooling을 섞어줍니다.

01:00:37.865 --> 01:00:43.766
그리고 여기 마지막에는 FC Layer가 있습니다.

01:00:43.766 --> 01:00:48.790
우리가 이전에 살펴본 FC와 똑같습니다.

01:00:48.790 --> 01:01:00.421
여기 마지막 Conv Layer의 출력은 3차원 volume으로 이루어집니다.

01:01:00.421 --> 01:01:16.275
이 값들을 전부 펴서(stretch) 1차원 벡터로 만듭니다.
그리고 이를 가지고 FC Layer의 입력으로 사용합니다.

01:01:16.275 --> 01:01:21.715
그렇게 되면 Conv Net의 모든 출력을 서로 연결하게
되는 것입니다.

01:01:22.676 --> 01:01:30.897
이 마지막 Layer부터는 공간적 구조(spatial structure)를
신경쓰지 않게 됩니다.

01:01:30.897 --> 01:01:43.185
전부 다 하나로 통합시키고는 최종적인 추론을 하게 됩니다.
그렇게 되면 Score가 출력으로 나오게 되는 것입니다.

01:01:45.744 --> 01:01:47.232
자 그럼..

01:01:47.232 --> 01:02:00.357
[학생이 질문]

01:02:00.357 --> 01:02:04.238
잘 못들었습니다??

01:02:04.238 --> 01:02:14.472
[학생이 질문]

01:02:15.772 --> 01:02:21.866
질문은 바로, 여기 열(col)들을 각각 어떻게 해석해야 하는지 입니다.
각 열들의 위에는 POOL같은 것들이 써있죠

01:02:21.866 --> 01:02:29.676
우선 여기 보이는 것들은 출력 Activation map입니다.

01:02:29.676 --> 01:02:31.187
각 출력들은 하나의 Layer의 결과 값입니다.

01:02:31.187 --> 01:02:41.837
처음부터 한 번 살펴보겠습니다. 처음에 Conv Layer를 거치면
activation map이 나옵니다.

01:02:41.837 --> 01:02:59.570
그리고 ReLU를 거칩니다. 그리고 Pooling Layer는 그
ReLU의 출력을 입력으로 받아서 Downsampling 하는 것입니다.

01:02:59.570 --> 01:03:05.810
Pooling 을 통해 Downsample합니다.

01:03:05.810 --> 01:03:13.004
Pool Layer의 출력을 한 번 보면
RELU의 출력과 비슷하게 생겨 보입니다.

01:03:13.004 --> 01:03:23.834
하지만 ReLU의 출력을 Downsample한 것이죠.
눈으로 보기에는 비슷하게 생겼을 수 있습니다.

01:03:23.834 --> 01:03:26.751
[학생이 질문]

01:03:31.823 --> 01:03:38.291
질문은 저 결과만 보면 정보 자체는 엄청 적을 것 같은데
저 정보만 가지고 어떻게 분류를 할 수 있는지 입니다.

01:03:38.291 --> 01:03:51.996
우선 저기 오른쪽 맨 끝에있는 Pool Layer의 출력 값은
전체 네트워크를 통과한 집약체라고 할 수 있습니다.

01:03:51.996 --> 01:03:58.902
그러므로 우리가 만든 계층구조의 최상위라고 할 수 있습니다.
실제로 Higher level concept을 표현하고 있는 것들입니다.

01:03:58.902 --> 01:04:04.871
예전에 Hubel and Wiesel의 예를 보았고, 이를 기반으로
우리는 필터를 계층적으로 쌓아 올렸습니다.

01:04:04.871 --> 01:04:11.557
최하위 계층에서는 edges 와 같은 단순한 구조를 찾아냅니다.

01:04:11.557 --> 01:04:24.000
그러니 여기 첫번째 열(col)의 map들이 의미하는 것은
각 자리에서 edges같은 것들이 얼마나 존재하는지를 의미합니다.

01:04:24.000 --> 01:04:28.215
그리고 지나면 지날수록 더 복잡한 것들을 찾아냅니다.

01:04:28.215 --> 01:04:37.380
두 번째 레이어에서는 (edge보다 복잡한) corner
같은 것이 얼마나 있는지를 보여주는 것입니다.

01:04:37.380 --> 01:04:43.927
각 Conv의 입력이 원본 이미지(자동차)가 아닙니다.
이전 레이어에서 나온 edge maps과 같은 것들이죠

01:04:43.927 --> 01:04:50.352
이런 edge map을 가지고 더 복잡한 것들을 추론을 하는 것입니다.

01:04:50.352 --> 01:04:58.679
마지막 pooling layer를 거치기 전까지의 각 값들은
각 필터가 가진 templete이 얼마나 활성되었는지를 표현합니다.

01:05:00.065 --> 01:05:11.811
그리고 이런 정보를 가지고 FC Layer를 거치게 되면,
그 정보들을 한데 모아 클래스 스코어를 계산하는 것입니다.

01:05:11.811 --> 01:05:18.351
요약하자면, 각 값들이 의미하는 것은 필터의 Templete이
얼마나 활성화 되었는가를 의미하는 것입니다.

01:05:20.343 --> 01:05:21.760
질문 있나요?

01:05:21.760 --> 01:05:24.539
[학생이 질문]

01:05:24.539 --> 01:05:28.596
질문은 바로 Classification 문제를 푸는데
pooling을 얼마나 해야하는지를 어떻게 아는지 입니다.

01:05:28.596 --> 01:05:32.022
제 대답은, 그저 여러분이 시도해 봐야 한다는 것입니다.

01:05:32.022 --> 01:05:38.730
실제로 여러분이 어떤 Design choices를 할때
조금의 직관은 가질 수 있습니다.

01:05:38.730 --> 01:05:47.260
Pool을 너무 많이하면 값이 너무 작아질 것이고
전체 이미지를 잘 표현하지 못하겠죠

01:05:47.260 --> 01:05:53.590
때로는 조금의 직관이 있을수도 있겠지만,
일반적으로는 다양한 옵션을 시도해 봅니다.

01:05:53.590 --> 01:06:00.792
다양한 pooling 사이즈, 필터 크기, 레이어 수 등을 시도해 보는
등의 Crossvalidation을 해야 할 것입니다

01:06:00.792 --> 01:06:11.640
그리고 가장 좋은 것을 찾는 것이지요. 어떤 하이퍼파라미터가 좋은지는
어떤 문제이냐에 따라 달라질 수 있습니다.

01:06:14.688 --> 01:06:27.724
그리고 마지막으로 이 demo를 보여드리겠습니다. CS231N강의를 만든
Andre Kapathy의 작품입니다.

01:06:27.724 --> 01:06:37.174
이 Demo는 CIFAR-10을 학습시킵니다. CIFAR-10은 이전에
살펴봤습니다. 10개의 클래스를 가지고 있죠.

01:06:37.174 --> 01:06:45.560
이 Demo가 좋은점은 실제로 Filter가 어떻게 생겼고
Activation Map이 어떻게 생겼는지를 볼 수 있다는 점입니다.

01:06:45.560 --> 01:06:49.135
앞서 슬라이드에서 소개했던 이미지 중 일부는
이 Demo에서 가져온 것들입니다.

01:06:49.135 --> 01:06:56.568
각자 demo에 접속해서 activation map이 어떻게
생겼는지도 한 번씩 보면 좋을 것 같습니다.

01:06:56.568 --> 01:07:03.009
그리고 대게는 가장 처음에 있는 Layer의 activation map은
여러분도 해석할 수 있을 것입니다.

01:07:03.009 --> 01:07:06.832
첫 번째 Layer의 입력은 원본 이미지 이기 때문에
직관적으로 이 template이 의미하는것이 무엇인지를 알 수 있습니다.

01:07:06.832 --> 01:07:12.463
반면 더 높은 Layer로 가면 갈수록 해당 Layer가 무슨
일을 하는지 해석하기가 점점 힘들어 집니다.

01:07:12.463 --> 01:07:18.835
그런 레이어들을 해석하지 못한다고 너무 상심하지 마세요

01:07:18.835 --> 01:07:23.571
Demo를 보며 흐름이 어떻게되고 출력이 어떻게 되는지를
전체적으로 살펴보는 것 만으로도 좋습니다.

01:07:25.285 --> 01:07:31.246
자 마지막으로 요약해보자면 오늘 우리는
CNN이 어떻게 동작하는지를 배웠습니다.

01:07:31.246 --> 01:07:39.591
기본적으로는 Conv 와 Pool 를 쌓아 올리다가
마지막에 FC Layer로 끝나게 됩니다.

01:07:39.591 --> 01:07:48.664
그리고 네트워크의 필터는 점점 더 작아지고, 아키텍쳐는 점점
깊어지는 경향을 배웠습니다. 나중에 예시를 더 다루겠습니다.

01:07:48.664 --> 01:07:53.515
그리고 Pooling 이나 FC Layer를 점점
더 없애는 추세이기도 합니다.

01:07:53.515 --> 01:08:02.358
그냥 Conv Layer만 깊게 쌓는 것입니다.
나중에 더 이야기 할 시간이 있을 것입니다.

01:08:03.198 --> 01:08:14.497
전형적인 CNN 아키텍쳐는 Conv와 ReLU를 몇 번(n번) 반복합니다.
그리고 그 중간에 pooling도 몇 번 들어갑니다.

01:08:14.497 --> 01:08:21.587
그리고 FC Layer가 이어집니다.
한 번에서 두 번 그 이상일수도 있습니다.

01:08:21.587 --> 01:08:25.360
그리고 Class score를 구하기 위해 softmax를 사용합니다.

01:08:25.360 --> 01:08:30.483
그리고 일반적으로 n은 5 정도가 될 수 있습니다.

01:08:31.708 --> 01:08:41.000
그렇게 되면 엄청 깊은 Conv, ReLU, Pool 시퀀스를 구성하게
될 것이고, 그다음 한두 번의 FC Layer가 이어지는 것입니다.

01:08:41.001 --> 01:08:51.055
그리고 다음 시간에는 더 최신의 다양한 아키텍쳐를 배우겠습니다.
ResNet이나 GoogLeNet 같은 것들이죠

01:08:51.056 --> 01:08:54.056
감사합니다. 수업 끝